# run.py (使用 Icarus Verilog)

import os
from pathlib import Path
from cocotb_test.simulator import run

def test_counter():
    project_root = Path(__file__).parent.resolve()
    sim_build = project_root / "sim_build"
    
    # 使用实际日志中显示的文件名和格式
    wave_file = sim_build / "counter_wave.fsdb"
    
    # 确保目录存在
    os.makedirs(sim_build, exist_ok=True)
    
    # 设置环境变量处理 X/Z 状态
    os.environ["COCOTB_RESOLVE_X"] = "ZEROS"
    
    run(
        verilog_sources=[str(project_root / "rtl" / "counter.sv")],
        toplevel="counter",
        module="tests.test_counter",
        python_search=[str(project_root / "tests")],
        includes=[str(project_root / "rtl")],
        simulator="icarus",
        compile_args=["-g2012", "-p", "timescale=1ns/1ps"],
        plusargs=[
            f"-o {wave_file}",
            "-s"  # 执行 VPI 初始化
        ],
        sim_args=["-l", "sim.log"]  # 生成仿真日志
    )
    
    # 检查波形文件 - 使用更灵活的检查
    wave_files = [
        sim_build / "counter_wave.fsdb",
        sim_build / "counter_waves.vcd",
        sim_build / "dump.fsdb",
        sim_build / "dump.vcd"
    ]
    
    found = False
    for file in wave_files:
        if file.exists() and file.stat().st_size > 1024:
            print(f"\n✅ 波形文件已生成: {file} ({file.stat().st_size} 字节)")
            print(f"查看波形: gtkwave {file}")
            found = True
            break
    
    if not found:
        print("\n❌ 未找到有效波形文件")
        print("\n调试建议:")
        print("1. 手动运行仿真:")
        print(f"   cd {sim_build}")
        print("   vvp -M $HOME/.local/lib/python3.10/site-packages/cocotb/libs -m libcocotbvpi_icarus counter.vvp")
        print("2. 检查日志:")
        print(f"   cat {sim_build}/sim.log")
        print("3. 尝试强制生成 VCD:")
        print("   在测试代码中添加: `cocotb.simulator.write_vcd('manual.vcd')`")

if __name__ == "__main__":
    test_counter()

import cocotb
from pyuvm import *
from cocotb.clock import Clock
from cocotb.triggers import FallingEdge, RisingEdge
from counter_uvm_test import *
from cocotb.triggers import Timer
import os
import sys
sys.path.append(os.path.join(os.getcwd(), "sim_build"))  # 添加Verilator生成路径
# 使用cocotb测试
async def test_counter(dut):
    """主测试入口"""
    await uvm_root().run_test("TestCounter")
    # 添加足够延迟确保波形写入
    await Timer(100, "ns")
# 10. 测试用例
@pyuvm.test()
class TestCounter(CounterTest):
    async def run_phase(self):
        self.raise_objection()
        # 添加足够延迟确保波形写入
        await Timer(1000, "ns")
        # 1. 设置时钟和复位
        dut = cocotb.top
        
        # 创建时钟 - 使用正确的信号名
        clock = Clock(dut.clk, 10, units="ns")
        cocotb.start_soon(clock.start(start_high=False))
        
        # 复位序列
        dut.rst_n.value = 0
        await Timer(20, "ns")
        dut.rst_n.value = 1
        await Timer(10, "ns")
        
        # 2. 启动测试序列
        seq = CounterSequence.create("seq")
        await seq.start(self.env.agent.seqr)
        
        # 3. 等待足够长时间，确保波形写入
        await Timer(1000, "ns")
        cocotb.log.info(f"🛑 准备结束测试，当前时间: {get_sim_time(units='ns')} ns")
        try:
            if hasattr(cocotb.simulator, "write_vcd"):
                cocotb.simulator.write_vcd("manual_waves.vcd")
            else:
                self.logger.warning("⚠️ 无法手动保存波形")
        except:
            self.logger.warning("⚠️ 无法手动保存波形")
        self.drop_objection()